// Copyright (c) 2019 Presto Labs Pte. Ltd.
// Author: xguo

#pragma once

#include <cstdint>
#include <functional>
#include <iostream>
#include <string>

#include <glog/logging.h>

#include "coin/proto/symbology.pb.h"
#include "coin2/exchange/base/market/enums.h"

namespace coin2::exchange::base::symbology {

using MarketType = market::MarketType;
using ExchangeType = market::ExchangeType;

class ISymbol {
 public:
  virtual const std::string& symbol() const = 0;
  virtual const std::string& native_symbol() const = 0;
};

inline bool operator<(
    const coin2::exchange::base::symbology::ISymbol& lhs,
    const coin2::exchange::base::symbology::ISymbol& rhs) {
  return lhs.symbol() < rhs.symbol();
}

inline bool operator==(
    const coin2::exchange::base::symbology::ISymbol& lhs,
    const coin2::exchange::base::symbology::ISymbol& rhs) {
  return lhs.symbol() == rhs.symbol();
}

inline std::ostream& operator<<(
    std::ostream& os,
    const coin2::exchange::base::symbology::ISymbol& symbol) {
  return os << symbol.symbol();
}

}  // namespace coin2::exchange::base::symbology

namespace std {

template <>
struct hash<coin2::exchange::base::symbology::ISymbol> {
  using ISymbol = coin2::exchange::base::symbology::ISymbol;
  std::size_t operator()(const ISymbol& symbol) const {
    return std::hash<std::string>()(symbol.symbol());
  }
};

}  // namespace std
